/**
 * This jQuery plugin displays pagination links inside the selected elements.
 *
 * @author Gabriel Birke (birke *at* d-scribe *dot* de)
 * @version 1.2
 * @param {int} maxentries Number of entries to paginate
 * @param {Object} opts Several options (see README for documentation)
 * @return {Object} jQuery Object
 */
function Pagination(panel,opts) {
	var self = this;
	$.extend(self, {
		numPages: function() {
			return Math.ceil(opts.maxentries/opts.items_per_page);
		},
		getInterval: function() {
			var ne_half = Math.ceil(opts.num_display_entries/2);
			var np = self.numPages();
			var upper_limit = np-opts.num_display_entries;
			var start = opts.current_page>ne_half?Math.max(Math.min(opts.current_page-ne_half, upper_limit), 0):0;
			var end = opts.current_page>ne_half?Math.min(opts.current_page+ne_half, np):Math.min(opts.num_display_entries, np);
			return [start,end];
		},
		onRequest:function() {
			panel.empty();
            opts.ajax.on ? (opts.ajax.ajaxStart(), $.ajax({
                url: opts.ajax.url,
                type: opts.ajax.type,
                data: opts.ajax.param(opts.current_page,opts.items_per_page),
                contentType: "application/x-www-form-urlencoded;utf-8",
                async: !0,
                cache: !0,
                timeout: 6e4,
                error: function(req) {
                	if(opts.ajax.error)
                	opts.ajax.error(req);
                },
                success: function(a) {
                	self.responseHandle(a),
                	self.drawLinks();
                }
            })) : self.drawLinks();
        },
		responseHandle:function(data) {
        	if(data.code == 0){
        		opts.ajax.onError(data);
        	}else {
        		opts.maxentries = data.totalRow;
            	opts.items_per_page = data.pageSize;
                opts.current_page =  data.pageNumber-1,
                opts.ajax.callback(data);
        	}
        },
		
		/**
		 * This is the event handling function for the pagination links. 
		 * @param {int} page_id The new page number
		 */
		pageSelected:function(page_id){
			opts.current_page = page_id;
			if (self.timer) {
				clearTimeout(self.timer);
			}
			self.timer = setTimeout(function () {
				self.onRequest();
			}, opts.typeDelay);
		},
		
		/**
		 * This function inserts the pagination links into the container element
		 */
		drawLinks:function() {
			var np = self.numPages();
			if(np < 2)return;
			var interval = self.getInterval();
			
			// This helper function returns a handler function that calls pageSelected with the right page_id
			
			// Helper function for generating a single link (or a span tag if it's the current page)
			var appendItem = function(page_id, appendopts){
				page_id = page_id<0?0:(page_id<np?page_id:np-1); // Normalize page id to sane value
				appendopts = jQuery.extend({text:page_id+1, classes:""}, appendopts||{});
				if(page_id == opts.current_page){
					var lnk = jQuery("<span class='current'>"+(appendopts.text)+"</span>");
				}
				else
				{
					var lnk = jQuery("<a page-id="+page_id+">"+(appendopts.text)+"</a>")
						.bind("click", function(){self.pageSelected(parseInt($(this).attr("page-id"))); return false;})
						.attr('href', opts.link_to.replace(/__id__/,page_id+1));
						
						
				}
				if(appendopts.classes){lnk.addClass(appendopts.classes);}
				panel.append(lnk);
			}
			// Generate "Previous"-Link
			if(opts.prev_text && (opts.current_page > 0 || opts.prev_show_always)){
				appendItem(opts.current_page-1,{text:opts.prev_text, classes:"prev"});
			}
			// Generate starting points
			if (interval[0] > 0 && opts.num_edge_entries > 0)
			{
				var end = Math.min(opts.num_edge_entries, interval[0]);
				for(var i=0; i<end; i++) {
					appendItem(i);
				}
				if(opts.num_edge_entries < interval[0] && opts.ellipse_text)
				{
					jQuery("<span>"+opts.ellipse_text+"</span>").appendTo(panel);
				}
			}
			// Generate interval links
			for(var i=interval[0]; i<interval[1]; i++) {
				appendItem(i);
			}
			// Generate ending points
			if (interval[1] < np && opts.num_edge_entries > 0)
			{
				if(np-opts.num_edge_entries > interval[1]&& opts.ellipse_text)
				{
					jQuery("<span>"+opts.ellipse_text+"</span>").appendTo(panel);
				}
				var begin = Math.max(np-opts.num_edge_entries, interval[1]);
				for(var i=begin; i<np; i++) {
					appendItem(i);
				}
				
			}
			// Generate "Next"-Link
			if(opts.next_text && (opts.current_page < np-1 || opts.next_show_always)){
				appendItem(opts.current_page+1,{text:opts.next_text, classes:"next"});
			}
		},
		prevPage:function(){ 
			if (opts.current_page > 0) {
				self.pageSelected(opts.current_page - 1);
				return true;
			}
			else {
				return false;
			}
		},
		nextPage:function(){ 
			if(opts.current_page < numPages()-1) {
				self.pageSelected(opts.current_page+1);
				return true;
			}
			else {
				return false;
			}
		},
		getConf: function() {
			return opts;	
		}	
	});
	self.pageSelected(0);
}
jQuery.fn.pagination = function(opts){
	opts = jQuery.extend({
		maxentries:0,
		items_per_page:10,
		num_display_entries:10,
		current_page:0,
		num_edge_entries:0,
		link_to:"#",
		prev_text:"Prev",
		next_text:"Next",
		ellipse_text:"...",
		prev_show_always:true,
		next_show_always:true,
		typeDelay:200,
		ajax: {
            on: !1,
            type: "get",
            url: "",
            dataType: "json",
            param:function(currentPage,pageSize){
            	return "";
            },
            ajaxStart: function() {
            	return false;
            },
            error:false,
            callback: function(data) {
            	return false;
            }
        }
	},opts||{});
	
	this.each(function() {			
		var el = new Pagination($(this),opts);
		$(this).data("pagination", el);
	});
};
jQuery.fn.getPagination = function() {
    return this.data("pagination")||false;
};


